/**
 * COMMON UI FUNCTIONS
 */

// Initialize loading animation
function initLoadingAnim(opts){
	var options = {
		title: '',
		modal: true,
		draggable: false,
		resizable: false,
		message: '',
		minWidth: 'auto',
		minHeight: 'auto',
		width: 'auto',
		height: 'auto',
		position: 'center',
		dialogClass: 'loading-anim-dialog'
	};
	$.extend(options, opts);
	
	// Remove previous dialog
	if($('#loading-anim').size()){
		$('#loading-anim').remove();
	}
	
	var div = $('<div id="loading-anim" class="body" style="display:none">' +
		'<img width="160" height="20" id="loading-anim-img" src="" />' +
		( options.message ? '<span>' + options.message + '</span>' : '' ) +
	'</div>');
	$(div).data('options', options);
	$('body').append(div); // Preload images
}

// Show loader animation
function showLoadingAnim(options){
	if($('#loading-anim').size() == 0 || typeof(options) != 'undefined'){
		initLoadingAnim(options);
	}
	options = $('#loading-anim').data('options');
	$('#loading-anim').dialog(options).dialog('open');	
	
	// Prevent stopped gif anim in some browsers
	setTimeout(function(){
		var src = $('#loading-anim-img').attr('src');
		$('#loading-anim-img').attr('src', src);
	}, 200);
}

// Hide loader animation
function hideLoadingAnim(){
	if ($('#loading-anim').size() && $('#loading-anim').hasClass('ui-dialog-content')) {
		$('#loading-anim').dialog('close');
	}
}

/**
 * Convert a form into an ajax form
 * Options:
 * - form : form element
 * - success : success handler function
 * - error : error handler function
 * - beforeSubmit : function to trigger before submitting
 */
function initAjaxForm(options){
	
	if(!options.errorsContainer){
		options.errorsContainer = '#error-messages';
	}
	if(!options.messagesContainer){
		options.messagesContainer = '#normal-messages';
	}
	if(typeof(options.preventDoubleSubmission) == 'undefined'){
		options.preventDoubleSubmission = true;
	}
	
	var ajaxFormOpts = {
		dataType: 'json'
	};
	
	var form = $(options.form);
	
	// Override default options
	$.extend(ajaxFormOpts, options);
	
	// Set before submit handler
	ajaxFormOpts.beforeSubmit = function(arr, $form, ajaxOptions) { 
		
		// Prevent double form submission
		if(options.preventDoubleSubmission && $form.data('_submitting')){
			return false;
		}
			
		$form.data('_submitting', true);
		
		clearErrors(options.errorsContainer); // Clear previous errors
		clearMessages(options.messagesContainer); // Clear previous messages
		
		// Trigger before submit handler
		if(options.beforeSubmit){
			var result = options.beforeSubmit.call($form, arr, $form, ajaxOptions);
			if(result === false){ // Prevent form submission
				$form.data('_submitting', false);
				return false;
			}
		}
		
		showLoadingAnim(); // Show loading animation
	};
    
	// Setup success handler
	ajaxFormOpts.success = function(response){
		form.data('_submitting', false);
		hideLoadingAnim();
		// Show action messages
		if(response.ajaxMessages && response.ajaxMessages.length > 0)
			showMessages(response.ajaxMessages, options.messagesContainer);
		if(response.ajaxResult == "success"){
			// Invoke success handler
			if(options.success){
				options.success.call(form, response);
			}
		}else if(response.ajaxResult == "session_timeout"){
			// Session timed out, display message
			
			var message = getI18nKey("page.session_timeout.text") + '. <a href="/account/login">' + getI18nKey("home.header.login") + '</a>';
			showMessages([message]);
			
		}else{
			// Show validation errors
			if(response.ajaxErrors && response.ajaxErrors.length > 0)
				showErrors(response.ajaxErrors, options.errorsContainer);
			// Focus first form input
			var firstInput = form.find('input,select,textarea,button').eq(0);
			if(!firstInput.is(':hidden'))
				firstInput[0].focus();
			// Invoke error handler
			if(options.error){
				options.error.call(form, response);
			}
		}
	};
	
	// Setup error handler
	ajaxFormOpts.complete = function(response){
		form.data('_submitting', false);
	};
	
	// Initialize ajax form
	$(options.form).ajaxForm(ajaxFormOpts);
	
}

/*
 * Convert form fields into a js object
 */
function serializeForm(form){
    var data = {};
    var fields = $(form).serializeArray();
    $.each(fields, function() {
    	if (data[this.name] !== undefined) {
            if (!data[this.name].push) {
            	data[this.name] = [data[this.name]];
            }
            data[this.name].push(this.value || '');
        } else {
        	data[this.name] = this.value || '';
        }
    });
    return data;
}

/**
 * Fill form inputs with the given data
 * @param form
 * @param data
 */
function fillForm(form, data){
	
	form = $(form);
	
	if(data){
		for(var key in data){
			var value = data[key];
			var input = form.find('[name="'+key+'"]');
			
			if (input.size() > 0){
				if(input.is('[type="radio"]') || input.is('[type="checkbox"]')){
					input.filter('[value="' + value + '"]')
						.attr('checked', 'checked');
				} else {
					if(input.is('select')){
						
						value = value !== null ? value : "";
						
						// Update selectmenu value
						if(typeof input.attr('aria-disabled') != 'undefined'){
							try{
								$(input).selectmenu('value', value);
							}catch(e){ }
						}else{
							input.val(value);
							input.trigger('change');
						}
					}else{
						input.val(value);
					}
				}
			}
		}
	}
};

// Handle generic ajax failure
function handleAjaxFailure(response, errorsContainer){
	
	if(response.ajaxErrors && response.ajaxErrors.length > 0){
		showErrors(response.ajaxErrors, errorsContainer);
	}
	
	hideLoadingAnim();
}

/**
 * Default Ajax error handler
 */
$(document).ajaxError(function(event, xhr, settings, error) {
	
	var messages = [];
	var displayErrorMessages = false;

	if (xhr.status == 0) { // Lost connection
    	messages.push('您是离线！请检查您的网络');
	}
	else if (xhr.status == 401) { // Need to authenticate
		var loginUrl = '/account/login?nextUrl=' + location.pathname + location.search;
		messages.push('您的会话已过期因闲置。 <a href="' + loginUrl + '">请重新登录</a>');
    }
	else if (xhr.status == 403) { // Need privileges
		messages.push('您没有足够的权限去完成这个动作');
    }
    else if (xhr.status == 404) { // Resource not found
    	messages.push('找不到资源');
    }
    else if (xhr.status == 413) { // Request entity too large
    	messages.push('总文件大小超过最大容许值（100MB）');
    }
    else if (xhr.status == 500) { // Internal server error
    	messages.push('发生意外错误。请刷新页面');
    }
    else if (error == 'parsererror') { // Error parsing json response
    	messages.push('发生意外错误。请刷新页面');
    }
    else if (error == 'timeout') { // Response timed out
    	messages.push('发生意外错误。请刷新页面');
    }
    else { // Unknown status code
    	
    	if(settings.error){
    		// Custom error handler specified
    		return;
    	}
    	
    	var contentType = xhr.getResponseHeader("Content-type");

        try{
        	// Attempt to get error message from json response
        	var response = $.parseJSON(xhr.responseText);
        	// Grab errors from response object
        	if(response.ajaxErrors){
        		messages = response.ajaxErrors;
        	}else if(response.errors){
        		messages = response.errors;
        	}
        	
        	if(xhr.status == 412){ // Precondition failed (Validation error)
        		displayErrorMessages = true;
        	}
        }catch(e){
        	// Not a json response
        }
    }
	
	// Default message
	if(messages.length == 0){
		messages.push('发生意外错误。请刷新页面');
	}
	
	if(displayErrorMessages){
		showErrors(messages, settings.errorsContainer);
	}else{
		showMessages(messages, settings.messagesContainer);
	}
	hideLoadingAnim();
});

// Show info dialog
function showInfoDialog(div, extraOptions){
	
	var dialog = $(div);
	
	var options = {
		modal : true,
		closeOnEscape : true,
		resizable : false,
		position : 'center',
		draggable : false,
		width : 500,
		height : 'auto',
		minHeight: '50px',
		show : 'fade',
		hide : 'fade',
		dialogClass: 'info-dialog',
		create : function(event, ui) {
			// Bind close button
			dialog.find('.close-dialog').click(function() {
				dialog.dialog('close');
			});
			
			// Call init function
			if(extraOptions.init){
				extraOptions.init.call(this, event, ui);
			}
		}
	};
	// Override default options
	if(extraOptions){
		$.extend(options, extraOptions);
	}
	
	// Open dialog 
	dialog.dialog(options).dialog('open');
}

// Close info dialog
function closeInfoDialog(div){
	// Close dialog 
	if($(div).hasClass('ui-dialog-content')){
		$(div).dialog('close');
	}
}

// Show error messages
function showErrors(errors, container, prepend){
	_showMessages(errors, (container ? container : $("#error-messages")), prepend);
}

//Remove error messages
function clearErrors(container){
	_clearMessages((container ? container : $("#error-messages")));
}

// Show normal messages
function showMessages(messages, container, prepend){
	_showMessages(messages, (container ? container : $("#normal-messages")), prepend);
}

// Remove normal messages
function clearMessages(container){
	_clearMessages((container ? container : $("#normal-messages")));
}

// Show success messages
function showSuccessMessages(messages, container, prepend,noTimeOut){
	_showMessages(messages, (container ? container : $("#success-messages")), prepend);
	if(noTimeOut!=true){
        // Hide automatically after 10 secs
        setTimeout(function(){
            clearSuccessMessages(container);
        }, 10000);
    }
}

// Remove normal messages
function clearSuccessMessages(container){
	_clearMessages((container ? container : $("#success-messages")));
}

// (private) Prepends a list of messages to a given container
function _showMessages(messages, container, prepend){
	var content = "";
	if(messages.length > 0){	
		for (i = 0; i < messages.length ; i++){
			content = content + messages[i] + "<br/>";
		}
		if(prepend){ // Prepend mode
			$(container).prepend(content);
		}else{ // Replace existent errors
			$(container).html(content);
		}
		if($(container).hasClass('hidden')){
			$(container).removeClass('hidden'); // Show container
			$(container).hide().fadeIn(); // Animate container
		}
		
		// Append close icon
		if($(container).find('.close').size() == 0){
			$(container).append('<span class="close"></span>');
			$(container).find('.close').click(function(){
				_clearMessages(container);
			});
		}
	}
}

// (private) Clear messages
function _clearMessages(container){
	$(container).fadeOut(function(){
		$(this).html(''); // Clear messages
		$(container).addClass('hidden'); // Hide container
	});
}


/**
 * Common formatting functions
 */
function ceilNumber(number, decimalDigits){
	if(typeof(decimalDigits) != 'undefined'){
		var offset = Math.pow(10, decimalDigits);
		number = number * offset;
		number = Math.ceil(number);
		number = number / offset;
	}
	return number;
}
function roundNumber(number, decimalDigits){
	if(typeof(decimalDigits) != 'undefined'){
		var offset = Math.pow(10, decimalDigits);
		number = number * offset;
		number = Math.round(number);
		number = number / offset;
	}
	return number;
}
function formatCurrencyWithoutUnit(number, forceDecimals, floorRounding) {
	return  formatNumber(number, 2, forceDecimals, floorRounding);
}
function formatCurrency(number, forceDecimals, floorRounding) {
	return '¥' + formatNumber(number, 2, forceDecimals, floorRounding);
}

function formatPercentage(number, forceDecimals, floorRounding){
	return formatNumber(number, 2, forceDecimals, floorRounding) + '%';
}

function formatNumberNoDecimals(number, floorRounding){
	return formatNumber(number, 0, false, floorRounding);
}

function formatNumber(number, decimalDigits, forceDecimals, floorRounding){
	
	var decSep = '.';
	var thoSep = ',';
	
	// Round number up or down
	if(typeof(decimalDigits) != 'undefined'){
		var offset = Math.pow(10, decimalDigits);
		number = number * offset;
		if(floorRounding){
			number = Math.floor(number);
		}else{
			number = Math.round(number);
		}
		number = number / offset;
	}

    var numberStr = '' + number;
    var parts = numberStr.split(decSep);
    
    var decimals = '';
    if(typeof(decimalDigits) != 'undefined') {
    	if(parts.length > 1)
    		decimals = parts[1];
    	if(forceDecimals){
	    	var diff = decimalDigits - decimals.length;
	    	// Append 0s
		    for(var i = 0; i < diff; i++){
		    	decimals += '0';
		    }
    	}
    }
    
    // Add thousands separator
    var integer = parts[0];
    var tsRegEx = /(\d+)(\d{3})/;
    while (tsRegEx.test(integer)){
    	integer = integer.replace(tsRegEx, '$1' + thoSep + '$2');
    }

    return integer + (decimals != '' ? decSep + decimals : '');
}

// Loan grade formatter 
function formatLoanGrade(loanGrade){
	return '<span class="loan-grade-format grade-' + loanGrade.toLowerCase() + '">' + loanGrade.toUpperCase() + '</span>';
}

// Loan status formatter
function formatLoanStatus(loanStatus){
	if(loanStatus == 'WARNING'){
		return '<span class="loan-status-format status-warning"></span>';
	}else{
		return '<span class="loan-status-format status-ok"></span>';
	}
}

// Empty formatter
function emptyFormatter(value){
	return '';
}

/* Common validation function */
function setupFormValidation(form, validateOptions,showErr){
	
	function showHideMessages(element){
		var div = $(element).closest("div").parent("div");
		div.removeClass('valid');
		div.removeClass('invalid');
		div.removeClass('error');
		div.removeClass('success');
		if(!$(element).rules().required && $(element).val() == ''){
			div.find('.messages').hide();
			return;
		}
		if($(element).hasClass('valid')){
			div.find('.messages').hide();
			div.addClass('success');
		}else if($(element).hasClass('error')){
			div.find('.messages').css('display', 'block');
			div.addClass('error');
		}
	}
	var _showErr=showErr;
	// Default options for validate plugin
	var options = {
		// Trigger validation after 2 secs ilde time
		onkeyup: function(element, event) { },
		errorPlacement: function(error, element) {
			var div = $(element).closest("div").parent("div");
			div.find('.messages .wrapper').append(error);
			//div.find('.messages').css('display', 'inline-block');
			showHideMessages(element);
		},
		onfocusin: function(element, event) {
			var div = $(element).closest("div").parent("div");
			div.addClass('focus');
			showHideMessages(element);
		},
		onfocusout: function(element, event) {
			
			var checkValidation = function(){
				var div = $(element).closest("div").parent("div");
				div.removeClass('focus');
				// Do live validation only on non-empty fields
				if($(element).val() != '' ||
						$(element).hasClass('valid') ||
						$(element).hasClass('error') ||
						!$(element).rules().required){
					$(element).valid();
				}
				showHideMessages(element);
			};
			
			// Delay validation if input has autocomplete
			if($(element).hasClass('ui-autocomplete-input')){
				setTimeout(function(){
					checkValidation();
				}, 100);
				return;
			}
			
			checkValidation();
		},
		success: function(error, element){
			error.remove();
			$(element).addClass('valid');
			showHideMessages(element);
		},
		focusInvalid: true,
		ignore: [] // Don't ignore hidden fields
	};
	
	if(validateOptions){
		$.extend(options, validateOptions);
	}
	
	// Initialize messages container
	$(form).find('.control-group .validate-msg').each(function(){
		// Append valid icon
		$(this).append('<span class="valid-icon"></span>');
		// Append messages container
		var messagesCont = $('<span class="messages"><span class="wrapper arrow-box"></span></span>');
		messagesCont.hide();
		$(this).append(messagesCont);
		
		// Move existent message labels to the wrapper
		$(this).find('.message_lbl').detach()
			.appendTo(messagesCont.find('.wrapper'));
		// Move existent help messages to the end of the div
		$(this).find('.help-message').detach().appendTo($(this));
	});

	// Bind form validation
	$(form).validate(options);
	
}

$(window).load(function(){
	
	// Add focus class to input elements
	$('button,input.text,select,textarea').bind('focus blur',function(){ $(this).toggleClass('focus') });
	
	// Focus first element
	var firstInput = $('form.standard').find('input.text, select, textarea, button').eq(0);
	if(firstInput.size() > 0 && !firstInput.hasClass('prevent-autofocus') && !firstInput.is(':hidden')){
		firstInput[0].focus();
	}
	
	// Display warning message if user is using IE6 or lower
	if(checkIfOldIE(6)){
		//var messageStr = "本网站不为这个浏览器进行了优化，可以考虑升级享受更好的体验。";
		var messageStr = 
			"本网站不为这个浏览器进行了优化，建议您将浏览器升级到&nbsp;<a href='http://windows.microsoft.com/zh-CN/internet-explorer/downloads/ie-8' target='_blank'>Internet Explorer 8</a>"+
			"、<a href='http://www.google.cn/intl/zh-CN/chrome/browser/' target='_blank'>Chrome</a>、<a href='http://www.firefox.com.cn/download/' target='_blank'>Firefox</a>&nbsp;享受更好的体验。";
		showMessages([messageStr]);
	}
});

/**
 * Checks if browser is IE. If called with a version number,
 * it will check if the browser version is lower or equal than
 * the given fromVersion 
 * 
 * @param fromVersion
 * @return true or false according to the fromVersion
 */
function checkIfOldIE(fromVersion){
	var ieMatch = navigator.userAgent.match('MSIE ([0-9]+)');
	var ieVersion = ieMatch && ieMatch.length > 1 ? ieMatch[1] : 'unknown';
	
	if(ieVersion == 'unknown') // Not IE
		return false;
	if(fromVersion == null){
    	return (ieVersion*1 <= 8);
    }else{
    	return (ieVersion*1 <= fromVersion*1);
    }
}

/**
 * Checks if browser is IE
 * @param fromVersion
 * @return true or false according to the fromVersion
 */
function isIE(){
	var ieMatch = navigator.userAgent.match('MSIE ([0-9]+)');
	return ieMatch && ieMatch.length > 1;
}

/**
 * Style file input unobstrusively
 */
function setupFileInput(fileInput, width){
	
	if(checkIfOldIE(7)) return; // Do not apply in IE6-7
	
	$(fileInput).wrap('<span class="file-input-wrapper" />');
	
	var wrapper = $(fileInput).parent();
	wrapper.prepend('<span class="filename"></span><span class="button ok-button browse">' + getI18nKey('page.documents.browse_files') +'</span>');
	
	wrapper.css('width', width);
	
	// Setup change event
	$(fileInput).change(function(){
		var label = $(this).parent().find('.filename');
		label.text($(this).val());
	});
}
function loanTermFormatter(val){
	if(isNaN(val)){
		return val;
	}
	return val;
}
function paymentTableAmountFormatter(val,data){
	var result='';
	if(data.number==0){
		return '';
	}else if(data.number==1){
		result= formatCurrency(val,2);
	}else{
		result= formatCurrencyWithoutUnit(val,2);
	}
	return result;
}
function boldAmountFormatter(val,data){
	var result='';
	if(data.number==0){
		return '';
	}else if(data.number==1){
		result= formatCurrency(val,2);
	}else{
		result= formatCurrencyWithoutUnit(val,2);
	}
	result="<b>"+result+"</b>";
	return result;
}
function summaryFormat(){
	return "总计 ";
}

function speBoldAmountFormatter(val,data){
	var result='';
	if(data.number<=1){
		result= formatCurrency(val,2);
	}else{
		result= formatCurrencyWithoutUnit(val,2);
	}
	result="<b>"+result+"</b>";
	return result;
}
function summaryFormat(){
	return "总计 ";
}

function sumFn(currentValue, newValue){
	if(!newValue)
		newValue = 0;
	if(!currentValue)
		currentValue = 0;
	return roundNumber(currentValue,2) + roundNumber(newValue,2);
}

/**
 * Setup question tips
 */
$(function(){
	$('.question-tip').hover(function(){
		$(this).find('.message').removeClass('hidden').fadeIn();//.css({top:"-20px",left:"35px"})
	},function(){
		$(this).find('.message').fadeOut();
	});
});